package link.anycar.study.current.latch;

import java.time.Instant;
import java.util.Random;
import java.util.concurrent.CountDownLatch;

/**
 * When to use count latch?
 *  Like the start of a journey, the bus starts until everyone arrives.
 */
public class Latch {

    static Random rnd = new Random(System.currentTimeMillis());

    public static void main(String[] args) {
        CountDownLatch latch = new CountDownLatch(5);
        for (int i=0; i<5; i++) {
            int tourist = i + 1;
            new Thread(() -> {
                // the tourist comes at different time
                sleep(rnd.nextInt(2) + 1);
                System.out.println("Tourist " + tourist + " arriving at " + Instant.now());

                // telling the conductor he/she arrives
                latch.countDown();
            }).start();
        }

        try {
            // conductor waits until everyone arrives
            latch.await();
            System.out.println("Everyone arrives, the bus starting at " + Instant.now());
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println();
        System.out.println("Start a new journey ...");
        CountDownLatch newLatch = new CountDownLatch(5);
        for (int i=5; i<10; i++) {
            int tourist = i + 1;
            new Thread(() -> {
                // the tourist arrives at different time
                sleep(rnd.nextInt(2) + 1);

                // but starts and does not at the bus until everyone arrives
                System.out.println("Tourist " + tourist + " starts his/her journey at " + Instant.now());
                sleep(rnd.nextInt(5) + 1);

                // and telling the conductor he/she ends his/her journey
                newLatch.countDown();

                // but instead waiting at the at the end of the journey, strange right?
                try {
                    newLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Tourist " + tourist + " finishes his/her journey at " + Instant.now());
            }).start();
        }
    }

    static void sleep(int second) {
        try {
            Thread.sleep(second * 1000);
        } catch (Exception e){}
    }
}
